﻿using UnityEngine;

namespace Share
{
    [RequireComponent(typeof(MeshFilter), typeof(MeshRenderer))]
    public class MeshSector : MonoBehaviour
    {
        [Header("扇形设置")]
        public float radius = 1f; // 扇形半径
        public Vector2 faceDir = Vector2.right; // 扇形朝向方向
        public float angle = 90f; // 扇形角度（度）
        public int segments = 30; // 扇形分段数
        public Material sectorMaterial; // 扇形材质
        
        [Header("填充设置")]
        public Color fillColor = Color.white; // 填充颜色
        public bool enableFill = true; // 是否启用填充
        
        [Header("边框设置")]
        public Color borderColor = Color.black; // 边框颜色
        public float borderWidth = 0.05f; // 边框宽度
        public bool enableBorder = true; // 是否启用边框

        private Mesh mesh;
        private Vector3[] vertices;
        private int[] triangles;
        private Color[] colors;

        void Start()
        {
            GetComponent<MeshFilter>().mesh = mesh = new Mesh();
            mesh.name = "2D Sector Mesh";
            if (sectorMaterial != null)
            {
                GetComponent<MeshRenderer>().material = sectorMaterial;
            }
            GenerateSectorMesh();
        }

        void GenerateSectorMesh()
        {
            mesh.Clear();

            if (segments < 3) segments = 3; // 最少需要3个分段
            if (angle <= 0) angle = 1f; // 最小角度
            if (angle > 360) angle = 360f; // 最大角度
            if (borderWidth < 0) borderWidth = 0f; // 边框宽度不能为负
            if (borderWidth >= radius) borderWidth = radius * 0.9f; // 边框宽度不能超过半径

            // 计算顶点数量
            int borderVertexCount = enableBorder ? (segments + 1) * 2 : 0; // 边框的内外圈顶点
            int fillVertexCount = enableFill ? segments + 2 : 0; // 填充区域的顶点（中心点 + 边缘顶点）
            int totalVertexCount = borderVertexCount + fillVertexCount;

            vertices = new Vector3[totalVertexCount];
            colors = new Color[totalVertexCount];

            // 计算三角形数量
            int borderTriangleCount = enableBorder ? segments * 6 : 0; // 边框的三角形
            int fillTriangleCount = enableFill ? segments * 3 : 0; // 填充区域的三角形
            int totalTriangleCount = borderTriangleCount + fillTriangleCount;
            triangles = new int[totalTriangleCount];

            // 计算扇形的起始和结束角度
            float startAngle = Mathf.Atan2(faceDir.y, faceDir.x) * Mathf.Rad2Deg - angle / 2f;
            float endAngle = startAngle + angle;
            float angleStep = angle / segments;

            int vertexIndex = 0;
            int triangleIndex = 0;

            // 生成边框顶点（如果需要边框）
            if (enableBorder)
            {
                for (int i = 0; i <= segments; i++)
                {
                    float currentAngle = startAngle + i * angleStep;
                    float rad = currentAngle * Mathf.Deg2Rad;
                    float cos = Mathf.Cos(rad);
                    float sin = Mathf.Sin(rad);

                    // 外圈顶点（边框外缘）- 使用边框颜色
                    vertices[vertexIndex] = new Vector3(cos * radius, sin * radius, 0);
                    colors[vertexIndex] = borderColor;
                    vertexIndex++;

                    // 内圈顶点（边框内缘）- 使用边框颜色
                    vertices[vertexIndex] = new Vector3(cos * (radius - borderWidth), sin * (radius - borderWidth), 0);
                    colors[vertexIndex] = borderColor;
                    vertexIndex++;
                }

                // 生成边框三角形索引
                for (int i = 0; i < segments; i++)
                {
                    int baseIndex = triangleIndex;
                    int currentOuter = i * 2;
                    int currentInner = i * 2 + 1;
                    int nextOuter = (i + 1) * 2;
                    int nextInner = (i + 1) * 2 + 1;

                    // 第一个三角形（当前外 -> 下一个外 -> 当前内）
                    triangles[baseIndex] = currentOuter;
                    triangles[baseIndex + 1] = nextOuter;
                    triangles[baseIndex + 2] = currentInner;
                    // 第二个三角形（当前内 -> 下一个外 -> 下一个内）
                    triangles[baseIndex + 3] = currentInner;
                    triangles[baseIndex + 4] = nextOuter;
                    triangles[baseIndex + 5] = nextInner;

                    triangleIndex += 6;
                }
            }

            // 生成填充区域顶点（如果需要填充）
            if (enableFill)
            {
                int fillStartIndex = vertexIndex;
                
                // 中心点 - 使用填充颜色
                vertices[vertexIndex] = Vector3.zero;
                colors[vertexIndex] = fillColor;
                vertexIndex++;

                // 内圈顶点（与边框内圈顶点相同位置，但使用填充颜色）
                for (int i = 0; i <= segments; i++)
                {
                    float currentAngle = startAngle + i * angleStep;
                    float rad = currentAngle * Mathf.Deg2Rad;
                    float cos = Mathf.Cos(rad);
                    float sin = Mathf.Sin(rad);

                    vertices[vertexIndex] = new Vector3(cos * (radius - (enableBorder ? borderWidth : 0)), 
                                                       sin * (radius - (enableBorder ? borderWidth : 0)), 0);
                    colors[vertexIndex] = fillColor;
                    vertexIndex++;
                }

                // 生成填充区域三角形索引
                for (int i = 0; i < segments; i++)
                {
                    int baseIndex = triangleIndex;
                    int centerIndex = fillStartIndex; // 中心点
                    int currentEdge = fillStartIndex + 1 + i; // 当前边缘顶点
                    int nextEdge = fillStartIndex + 1 + i + 1; // 下一个边缘顶点

                    triangles[baseIndex] = centerIndex;
                    triangles[baseIndex + 1] = currentEdge;
                    triangles[baseIndex + 2] = nextEdge;

                    triangleIndex += 3;
                }
            }

            mesh.vertices = vertices;
            mesh.triangles = triangles;
            mesh.colors = colors;
            mesh.RecalculateNormals();
            mesh.RecalculateBounds();
        }

        /// <summary>
        /// 更新扇形参数
        /// </summary>
        public void UpdateSector(float newRadius, Vector2 newFaceDir, float newAngle)
        {
            radius = newRadius;
            faceDir = newFaceDir;
            angle = newAngle;
            GenerateSectorMesh();
        }

        /// <summary>
        /// 设置材质
        /// </summary>
        public void SetMaterial(Material newMaterial)
        {
            sectorMaterial = newMaterial;
            if (GetComponent<MeshRenderer>() != null)
            {
                GetComponent<MeshRenderer>().material = sectorMaterial;
            }
        }

        /// <summary>
        /// 设置填充颜色
        /// </summary>
        public void SetFillColor(Color newFillColor)
        {
            fillColor = newFillColor;
            GenerateSectorMesh();
        }

        /// <summary>
        /// 启用/禁用填充
        /// </summary>
        public void SetFillEnabled(bool enabled)
        {
            enableFill = enabled;
            GenerateSectorMesh();
        }

        /// <summary>
        /// 设置扇形朝向
        /// </summary>
        public void SetFaceDirection(Vector2 direction)
        {
            faceDir = direction.normalized;
            GenerateSectorMesh();
        }

        /// <summary>
        /// 设置扇形角度
        /// </summary>
        public void SetAngle(float newAngle)
        {
            angle = Mathf.Clamp(newAngle, 1f, 360f);
            GenerateSectorMesh();
        }

        /// <summary>
        /// 设置扇形半径
        /// </summary>
        public void SetRadius(float newRadius)
        {
            radius = newRadius;
            GenerateSectorMesh();
        }

        /// <summary>
        /// 设置边框颜色
        /// </summary>
        public void SetBorderColor(Color newBorderColor)
        {
            borderColor = newBorderColor;
            GenerateSectorMesh();
        }

        /// <summary>
        /// 设置边框宽度
        /// </summary>
        public void SetBorderWidth(float newBorderWidth)
        {
            borderWidth = Mathf.Clamp(newBorderWidth, 0f, radius * 0.9f);
            GenerateSectorMesh();
        }

        /// <summary>
        /// 启用/禁用边框
        /// </summary>
        public void SetBorderEnabled(bool enabled)
        {
            enableBorder = enabled;
            GenerateSectorMesh();
        }

        /// <summary>
        /// 在Inspector中修改参数后，可在编辑模式实时更新网格
        /// </summary>
        void OnValidate()
        {
            if (mesh != null)
            {
                GenerateSectorMesh();
            }
        }

        /// <summary>
        /// 在Scene视图中绘制Gizmos
        /// </summary>
        void OnDrawGizmosSelected()
        {
            if (!enabled) return;

            // 计算扇形的起始和结束角度
            float startAngle = Mathf.Atan2(faceDir.y, faceDir.x) * Mathf.Rad2Deg - angle / 2f;
            float endAngle = startAngle + angle;

            // 绘制扇形边界线
            Gizmos.color = Color.yellow;
            Vector3 center = transform.position;

            // 绘制起始边界线
            Vector3 startDir = Quaternion.Euler(0, 0, startAngle) * Vector3.right;
            Gizmos.DrawLine(center, center + startDir * radius);

            // 绘制结束边界线
            Vector3 endDir = Quaternion.Euler(0, 0, endAngle) * Vector3.right;
            Gizmos.DrawLine(center, center + endDir * radius);

            // 绘制弧线
            int gizmoSegments = Mathf.Max(8, Mathf.FloorToInt(segments / 2f));
            float gizmoAngleStep = angle / gizmoSegments;
            Vector3 prevPoint = center + startDir * radius;

            for (int i = 1; i <= gizmoSegments; i++)
            {
                float currentAngle = startAngle + i * gizmoAngleStep;
                Vector3 currentDir = Quaternion.Euler(0, 0, currentAngle) * Vector3.right;
                Vector3 currentPoint = center + currentDir * radius;
                Gizmos.DrawLine(prevPoint, currentPoint);
                prevPoint = currentPoint;
            }
        }
    }
}
